package libnetdb.dm.assoc.dhp;


public class HashPruner {

    private int hash_size[], hashtbl[][], support_lmt = 0, buffer[];
    private int hash_level, current_size;

    public HashPruner(int hash_size[], int hash_level) {
        this.hash_size = new int[hash_size.length];
        for(int i=0;i<hash_size.length;i++)
            this.hash_size[i] = hash_size[i];
        buffer = new int[this.hash_level = hash_level];
    }

    private int hash(int ids[], int n){
        int hash_code = 0x3714927B;
        for(int i=0;i<current_size;i++)
            hash_code = ((hash_code+n)*0x375F3AB7)^((ids[i]-n)*0x31571393)+0x2173319A;
        return Math.abs(hash_code)%hashtbl[n].length;
    }

    public void setSupportLimit(int support_lmt){
        this.support_lmt = support_lmt;
    }

    public void reset(int length){
        if(length <= hash_level){
            current_size = length;
            if(hashtbl==null){
                hashtbl = new int[hash_size.length][];
                for(int i=0;i<hashtbl.length;i++){
                    hashtbl[i] = new int[hash_size[i]];
                    for(int j=0;j<hash_size[i];j++) hashtbl[i][j] = 0;
                }
            }else{
                for(int i=0;i<hashtbl.length;i++)
                    for(int j=0;j<hash_size[i];j++) hashtbl[i][j] = 0;
            }
        }else hashtbl = null;
    }

    public boolean check(int ids[]){
        if(hashtbl==null||current_size!=ids.length) return true;
        for(int i=0;i<hashtbl.length;i++)
            if(hashtbl[i][hash(ids, i)] < support_lmt) return false;
        return true;
    }

    private void add_horse(int ids[], int selected[], int l, int k){
        if(k>0)
            for(int i=k-1;i<ids.length;i++){
        selected[k-1] = ids[i];
        add_horse(ids, selected, i, k-1);
            }
            else
                for(int i=0;i<hashtbl.length;i++)
                    hashtbl[i][hash(selected, i)] ++;
    }

    public void add(int ids[]){
        if(hashtbl==null || ids.length < current_size) return;
        add_horse(ids, buffer, ids.length, current_size);
    }
}